
#include "serial_uart.h"
#include "chip_control.h"
#include <math.h>

static int chip_set_color(int fd, int color_type)
{
    if(fd < 0 || color_type < 0 )
    {
        printf("fd or color_type is err!\n");
        return -1;
    }

    char buf[8] = {0xaa, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; 
    
    if(color_type <= IRON_RED_PSEUDO_COLOR && color_type >= WHITE_HOT || color_type == RAINBOW_PSEUDO_COLOR)
    {
        if(IRON_RED_PSEUDO_COLOR == color_type){
            buf[2] = 3;
        }else if(color_type == RAINBOW_PSEUDO_COLOR)
        {
            buf[2] = 2;
        }else{
            buf[2] = color_type;
        }
        buf[7] =  buf[1] + buf[2] + buf[3] + buf[4]  + buf[5] + buf[6];
        serial_write(fd, buf, sizeof(buf));
        return 0;
    }
   
    printf("Unsupport cmd!\n");
    return -1;
}

static int electronic_zoom(int fd, float multiple)
{
    // AA D4 00 04 00 00 00 D8  	//1x
    // AA D4 00 08 00 00 00 DC		//2x
    // AA D4 00 0c 00 00 00 E0		//3x
    // AA D4 00 10 00 00 00 E4		//4x
    // AA D4 00 14 00 00 00 E8		//5x
    // AA D4 00 18 00 00 00 EC		//6x
    // AA D4 00 1c 00 00 00 F0		//7x
    // AA D4 00 20 00 00 00 F4		//8x
    if(fd < 0 || multiple < 1 || multiple > 8)
    {
        printf("fd or multiple is not support!\n");
        return -1;
    }

    char buf[8] = {0xaa, 0xd4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; 
    float epsilon = 1e-5f;
    int tmp_value = 0;
    
    if (fabs(multiple - 1.0) < epsilon) {
        tmp_value = 1;
        buf[3] = 0x04 * tmp_value;
    }
    else if (fabs(multiple - 2.0) < epsilon) {
        tmp_value = 2;
        buf[3] = 0x04 * tmp_value;
    }
    else if (fabs(multiple - 3.0) < epsilon) {
        tmp_value = 3;
        buf[3] = 0x04 * tmp_value;
    }
    else  if(fabs(multiple - 4.0) < epsilon){
        tmp_value = 4;
        buf[3] = 0x04 * tmp_value;
    }
    else if (fabs(multiple - 5.0) < epsilon) {
        tmp_value = 5;
        buf[3] = 0x04 * tmp_value;
    }
    else if (fabs(multiple - 6.0) < epsilon) {
        tmp_value = 6;
        buf[3] = 0x04 * tmp_value;
    }else if (fabs(multiple - 7.0) < epsilon) {
        tmp_value = 7;
        buf[3] = 0x04 * tmp_value;
    }
    else if(fabs(multiple - 8.0) < epsilon) {
        tmp_value = 8;
        buf[3] = 0x04 * tmp_value;
    }
    else{
        printf("multiple [%.2f] Unsupport cmd!\n", multiple);
        return -1;
    }

    buf[7] =  buf[1] + buf[2] + buf[3] + buf[4]  + buf[5] + buf[6];
    serial_write(fd, buf, sizeof(buf));
   
    return 0;
}

static int manaual_shutter_calibration(int fd)
{
    if(fd < 0)
    {
        printf("fd  is err!\n");
        return -1;
    }

    // AA D0 00 00 00 00 00 D0
    char buf[8] = {0xaa, 0xd0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; 
    //checksum
    buf[7] =  buf[1] + buf[2] + buf[3] + buf[4]  + buf[5] + buf[6];

    serial_write(fd, buf, sizeof(buf));
    return 0;
}

static int shutter_calibration_switch(int fd, int enable_statu)
{
    if(fd < 0 || enable_statu < 0 || enable_statu > 1 )
    {
        printf("fd or color_type is err!\n");
        return -1;
    }
    // AA CF 01 00 00 00 00 D0 open
    char buf[8] = {0xaa, 0xcf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; 
    if(1 == enable_statu)
    {
        buf[2] = 0x01;
    }
    else
    {
        buf[2] = 0x00;
    }

    //checksum
    buf[7] =  buf[1] + buf[2] + buf[3] + buf[4]  + buf[5] + buf[6];

    serial_write(fd, buf, sizeof(buf));
    return 0;
}

/*5.图像水平翻转
*enable_statu:0x01 水平翻转180°
*enable_statu:0x00 恢复翻转
*/
static int horizontal_image_flip(int fd, int enable_statu)
{
    if(fd < 0 || enable_statu < 0 || enable_statu > 1 )
    {
        printf("fd or horizontal_image_flip is err!\n");
        return -1;
    }
    // AA B8 01 00 00 00 00 B9 open
    char buf[8] = {0xaa, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; 
    if(1 == enable_statu)
    {
        buf[2] = 0x01;
    }
    else
    {
        buf[2] = 0x00;
    }

    //checksum
    buf[7] =  buf[1] + buf[2] + buf[3] + buf[4]  + buf[5] + buf[6];

    serial_write(fd, buf, sizeof(buf));
    return 0;
}

/*6.图像垂直翻转
*enable_statu:0x01 垂直翻转180°
*enable_statu:0x00 恢复翻转
*/
static int vertical_image_flip(int fd, int enable_statu)
{
    if(fd < 0 || enable_statu < 0 || enable_statu > 1 )
    {
        printf("fd or vertical_image_flip is err!\n");
        return -1;
    }
    // AA B9 01 00 00 00 00 D0 open
    char buf[8] = {0xaa, 0xb9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; 
    if(1 == enable_statu)
    {
        buf[2] = 0x01;
    }
    else
    {
        buf[2] = 0x00;
    }

    //checksum
    buf[7] =  buf[1] + buf[2] + buf[3] + buf[4]  + buf[5] + buf[6];

    serial_write(fd, buf, sizeof(buf));
    return 0;
}

/*7.模拟视频开关
*enable_statu:0x01 模拟视频开
*enable_statu:0x00 模拟视频关
*/
static int analog_video_switch(int fd, int enable_statu)
{
    if(fd < 0 || enable_statu < 0 || enable_statu > 1 )
    {
        printf("fd or analog_video_switch is err!\n");
        return -1;
    }
    // AA d5 01 00 00 00 00 D0 open
    char buf[8] = {0xaa, 0xd5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; 
    if(1 == enable_statu)
    {
        buf[2] = 0x01;
    }
    else
    {
        buf[2] = 0x00;
    }

    //checksum
    buf[7] =  buf[1] + buf[2] + buf[3] + buf[4]  + buf[5] + buf[6];

    serial_write(fd, buf, sizeof(buf));
    return 0;
}

/*14.视频输出格式
*enable_statu:0x01 NTSC
*enable_statu:0x00 PAL
*/
static int output_video_format(int fd, int enable_statu)
{
    if(fd < 0 || enable_statu < 0 || enable_statu > 1 )
    {
        printf("fd or output_video_format is err!\n");
        return -1;
    }
    // AA e9 01 00 00 00 00 D0 open
    char buf[8] = {0xaa, 0xe9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; 
    if(1 == enable_statu)
    {
        buf[2] = 0x01;
    }
    else
    {
        buf[2] = 0x00;
    }

    //checksum
    buf[7] =  buf[1] + buf[2] + buf[3] + buf[4]  + buf[5] + buf[6];

    serial_write(fd, buf, sizeof(buf));
    return 0;
}

/*15.保存用户配置*/
static int save_user_config(int fd)
{
    if(fd < 0)
    {
        printf("fd or save_user_config is err!\n");
        return -1;
    }
    // AA ea 01 00 00 00 00 D0 open
    char buf[8] = {0xaa, 0xea, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00}; 
    //checksum
    buf[7] =  buf[1] + buf[2] + buf[3] + buf[4]  + buf[5] + buf[6];

    serial_write(fd, buf, sizeof(buf));
    return 0;
}

/*15.获取用户配置*/
static int get_user_config(int fd, char* recvbuf, int size)
{
    if(fd < 0 || !recvbuf || size < 0)
    {
        printf("fd or get_user_config is err!\n");
        return -1;
    }
    // aa eb 00 00 00 00 00 eb open
    char buf[8] = {0xaa, 0xeb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; 
    //checksum
    buf[7] =  buf[1] + buf[2] + buf[3] + buf[4]  + buf[5] + buf[6];

    serial_write(fd, buf, sizeof(buf));
    usleep(100);
    serial_read(fd, recvbuf, size);
   
    // int i=0;
    // for(int i=0; i<size; ++i){
    //     printf("%02x ", recvbuf[i]);
    // }
    // printf("\n");
    return 0;
}

int parse_hex_string(const char *input, unsigned char *output, int max_output_size) {
    if(!input || !output || max_output_size <= 0){
        return -1;
    }

    int len = strlen(input);
    int output_index = 0;

    int i = 0;
    while (i <= len - 4) { // 确保有足够的字符处理
        if (input[i] == '0' && (input[i+1] == 'x' || input[i+1] == 'X')) {
            // 提取后两位字符
            char hex_str[3];
            hex_str[0] = input[i+2];
            hex_str[1] = input[i+3];
            hex_str[2] = '\0';
            
            char *endptr;
            long val = strtol(hex_str, &endptr, 16);
            
            if (endptr != hex_str + 2) { // 检查转换是否成功
                printf("无效的十六进制数: %s,位置：%d\n", hex_str, i+2);
                i += 4;
                continue;
            }
            
            if(output_index >= max_output_size){
                printf("输出缓冲区已满，无法继续解析\n");
                return -1;
            }
            output[output_index++] = (unsigned char)val;
            i += 4; // 移动到下一个可能的0x位置
        } else {
            i++; // 继续查找
        }
    }

    return output_index;
}

// 计算校验和
uint8_t uchar_checksum(uint8_t *data, size_t length) {
    uint8_t sum = 0;
    for (size_t i = 0; i < length; i++) {
        sum += data[i];
    }
    return sum;
}

// 获取指定位的值
uint8_t get_bits(uint8_t start, uint8_t end, uint32_t value) {
    return (value >> start) & ((1 << (end - start + 1)) - 1);
}

void progress_bar(int progress, int total) {
    // 计算进度百分比
    float percentage = (float)progress / total * 100;

    // 打印进度条
    printf("\r["); // \r 将光标移动到行首
    int bar_width = 50; // 进度条宽度
    int pos = bar_width * percentage / 100;
    for (int i = 0; i < bar_width; i++) {
        if (i < pos) printf("="); // 已完成部分
        else if (i == pos) printf(">"); // 当前进度
        else printf(" "); // 未完成部分
    }
    printf("] %.2f%%", percentage); // 打印百分比
    fflush(stdout); // 刷新输出缓冲区
}

int  read_main_file(const char *filepath, int serial_fd, int *len) {
    FILE *file = fopen(filepath, "r");
    if (!file) {
        perror("Failed to open file");
        return -1;
    }

    // 读取文件内容到动态数组
    uint32_t *all_list = NULL;
    size_t size = 0;
    char line[256];
    while (fgets(line, sizeof(line), file)) {
        // 去除每行的空格和换行符
        char *trimmed_line = strtok(line, " \n");
        if (trimmed_line) {
            // 将十六进制字符串转换为整数
            uint32_t hex_value = strtoul(trimmed_line, NULL, 16);
            all_list = realloc(all_list, (size + 1) * sizeof(uint32_t));
            all_list[size++] = hex_value;
        }
    }
    fclose(file);

    printf("Size: %zu\n", size);
    *len = size;
    // 初始化变量
    uint32_t gain_start_address = 0x1000000;
    uint32_t tmp = 0x000000;

    // 文件数据分批发送
    for (size_t j = 0; j < size / 200; j++) {
        uint32_t gain_address = (j == 0) ? gain_start_address : tmp;

        // 准备要发送的数据
        uint8_t list[210]; // 126, 192, 255, 205 + 4字节地址 + 1字节长度 + 200字节数据 + 1字节校验
        list[0] = 126;
        list[1] = 192;
        list[2] = 255;
        list[3] = 205;
        list[4] = get_bits(0, 7, gain_address);   // 地址低位
        list[5] = get_bits(8, 15, gain_address);  // 地址中低位
        list[6] = get_bits(16, 23, gain_address); // 地址中高位
        list[7] = get_bits(24, 31, gain_address); // 地址高位
        list[8] = 200; // 读写长度

        // 填充数据
        for (size_t i = 0; i < 200; i++) {
            list[9 + i] = all_list[j * 200 + i];
        }

        // 计算校验和
        uint8_t sum = uchar_checksum(list + 4, 205); // 校验范围：4到208
        list[209] = sum;

        progress_bar(j, size /200);
        // 发送数据
        write(serial_fd, list, sizeof(list));

        // 更新地址
        tmp = gain_address + 200;
    }

    // 处理剩余的数据
    size_t remaining = size % 200;
    if (remaining > 0) {
        uint8_t list[9 + remaining + 1]; // 126, 192, 255 + 1字节长度 + 4字节地址 + 1字节长度 + 剩余数据 + 1字节校验
        list[0] = 126;
        list[1] = 192;
        list[2] = 255;
        list[3] = remaining + 5;
        list[4] = get_bits(0, 7, tmp);   // 地址低位
        list[5] = get_bits(8, 15, tmp);  // 地址中低位
        list[6] = get_bits(16, 23, tmp); // 地址中高位
        list[7] = get_bits(24, 31, tmp); // 地址高位
        list[8] = remaining; // 读写长度

        // 填充剩余数据
        for (size_t i = 0; i < remaining; i++) {
            list[9 + i] = all_list[(size / 200) * 200 + i];
        }

        // 计算校验和
        uint8_t sum = uchar_checksum(list + 4, remaining + 5); // 校验范围：4到8+remaining
        list[9 + remaining] = sum;

        // 发送数据
        write(serial_fd, list, sizeof(list));
    }

    // 释放动态数组
    free(all_list);

    printf("\nData sent successfully!\n");
    return 0;
}

int update_fpga_project(int serial_fd, int size){
    uint8_t list[17] = {0x7e, 0xdd, 0xff, 0xc, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0}; 
    list[12] = get_bits(0, 7, size);   // 地址低位
    list[13] = get_bits(8, 15, size);  // 地址中低位
    list[14] = get_bits(16, 23, size); // 地址中高位
    list[15] = get_bits(24, 31, size); // 地址高位

    uint8_t check_sum = uchar_checksum(list + 4, sizeof(list) - 4 - 1);
    list[16] = check_sum;

    int i=0;
    printf("fpga_sum:0x%x\n", check_sum);
    for(int i=0; i<sizeof(list); ++i){
        printf("%02x ", list[i]);
        if((i+1)%16 == 0){
            printf("\n");
        }
    }
    printf("\n");
    write(serial_fd, list, sizeof(list));
    return 0;
}

int update_riscv_project(int serial_fd, int size){
    uint8_t list[17] = {0x7e, 0xdd, 0xff, 0xc, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x10, 0x0}; 
    list[12] = get_bits(0, 7, size);   // 地址低位
    list[13] = get_bits(8, 15, size);  // 地址中低位
    list[14] = get_bits(16, 23, size); // 地址中高位
    list[15] = get_bits(24, 31, size); // 地址高位

    uint8_t check_sum = uchar_checksum(list + 4, sizeof(list) - 4 - 1);
    list[16] = check_sum;

    int i=0;
    printf("riscv_sum:0x%x\n", check_sum);
    for(int i=0; i<sizeof(list); ++i){
        printf("%02x ", list[i]);
        if((i+1)%16 == 0){
            printf("\n");
        }
    }
    printf("\n");
    write(serial_fd, list, sizeof(list));
    return 0;
}

int update_fpga_and_riscv_project(int serial_fd, int size){
    update_fpga_project(serial_fd, size);
    return 0;
}

int chip_ctrl_init(const char * device, int ctrl_type, NetworkCameraChipInfo *chip_ctrl){
    int serial_fd = serial_init(device);
    if (serial_fd < 0) {
        printf("serial_init failed!\n");
        return -1;
    }

    if(ctrl_type < CHIP_CRTL_PSEUDO_COLOR || ctrl_type > TEST_UPGRADE)
    {
        printf("chip_set_ctrl_type %d unsupport!\n",ctrl_type);
        goto end;
    }

    if(ctrl_type == CHIP_CRTL_PSEUDO_COLOR)
    {
        int value = chip_ctrl->pseudo_color;
        if(value < WHITE_HOT)
        {
            printf("chip_set_pseudo_color value %d is not availed!\n",value);
            goto end;
        }

        char color[128] = {0};
        strncpy(color,  value == BLACK_HOT?"BLACK_HOT":(value == RAINBOW_PSEUDO_COLOR?"RAINBOW_PSEUDO_COLOR":(value == IRON_RED_PSEUDO_COLOR?"IRON_RED_PSEUDO_COLOR":"WHITE_HOT")), sizeof(color));

        int ret = chip_set_color(serial_fd, value);
        if(ret < 0){
            printf("chip_set_color %s failed!\n",color);
            goto end;
        }
        printf("chip_set_color %s success!\n",color);
    }
    else if(ctrl_type == CHIP_CRTL_ELECTRONIC_ZOOM)
    {
        float value = chip_ctrl->electronic_zoom;

        if(value < 1 || value > 8)
        {
            printf("CHIP_CRTL_ELECTRONIC_ZOOM value %f is not availed!\n",value);
            goto end;
        }

        int ret = electronic_zoom(serial_fd, value);
        if(ret < 0){
            printf("chip_set_electronic_zoom %d failed!\n",value);
            goto end;
        }
        printf("chip_set_electronic_zoom %d success!\n",value);
    }
    else if(ctrl_type == CHIP_CRTL_SHUTTER_CALIBRATION)
    {
        int value = chip_ctrl->shutter_calibration;
        if(value < 0 || value > 1)
        {
            printf("CHIP_CRTL_SHUTTER_CALIBRATION value %d is not availed!\n",value);
            goto end;
        }

        int ret = shutter_calibration_switch(serial_fd, value);
        if(ret < 0){
            printf("CHIP_CRTL_SHUTTER_CALIBRATION %d failed!\n",value);
            goto end;
        }
        printf("CHIP_CRTL_SHUTTER_CALIBRATION %d success!\n",value);
    }
    else if(ctrl_type == CHIP_CRTL_MANUAL_SHUTTER_CALIBRATION)
    {
        int ret = manaual_shutter_calibration(serial_fd);
        if(ret < 0){
            printf("CHIP_CRTL_MANUAL_SHUTTER_CALIBRATION  failed!\n");
            goto end;
        }
        printf("CHIP_CRTL_SHUTTER_CALIBRATION success!\n");
    } else if(ctrl_type == CHIP_CRTL_HORIZONTAL_IMAGE_FLIP){
        int value = chip_ctrl->horizontal_image_flip;
        if(value < 0 || value > 1)
        {
            printf("CHIP_CRTL_HORIZONTAL_IMAGE_FLIP value %d is not availed!\n",value);
            goto end;
        }

        int ret =  horizontal_image_flip(serial_fd, value);
        if(ret < 0){
            printf("CHIP_CRTL_HORIZONTAL_IMAGE_FLIP  failed!\n");
            goto end;
        }
        printf("CHIP_CRTL_HORIZONTAL_IMAGE_FLIP success!\n");
    } else if(ctrl_type == CHIP_CRTL_VERTICAL_IMAGE_FLIP){
        int value = chip_ctrl->vertical_image_flip;
        if(value < 0 || value > 1)
        {
            printf("CHIP_CRTL_VERTICAL_IMAGE_FLIP value %d is not availed!\n",value);
            goto end;
        }

        int ret =  vertical_image_flip(serial_fd, value);
        if(ret < 0){
            printf("CHIP_CRTL_VERTICAL_IMAGE_FLIP  failed!\n");
            goto end;
        }
        printf("CHIP_CRTL_VERTICAL_IMAGE_FLIP success!\n");
    } else if(ctrl_type == CHIP_CRTL_ANALOG_VIDEO_SWITCH){
        int value = chip_ctrl->analog_video_switch;
        if(value < 0 || value > 1)
        {
            printf("CHIP_CRTL_ANALOG_VIDEO_SWITCH value %d is not availed!\n",value);
            goto end;
        }

        int ret =  analog_video_switch(serial_fd, value);
        if(ret < 0){
            printf("CHIP_CRTL_ANALOG_VIDEO_SWITCH  failed!\n");
            goto end;
        }
        printf("CHIP_CRTL_ANALOG_VIDEO_SWITCH success!\n");
    } else if(ctrl_type == CHIP_CRTL_OUTPUT_VIDEO_FORMAT){
        int value = chip_ctrl->output_video_format;
        if(value < 0 || value > 1)
        {
            printf("CHIP_CRTL_OUTPUT_VIDEO_FORMAT value %d is not availed!\n",value);
            goto end;
        }

        int ret =  output_video_format(serial_fd, value);
        if(ret < 0){
            printf("CHIP_CRTL_OUTPUT_VIDEO_FORMAT  failed!\n");
            goto end;
        }
        printf("CHIP_CRTL_OUTPUT_VIDEO_FORMAT success!\n");
    } else if(ctrl_type == CHIP_CRTL_SAVE_USER_CONFIG){
        int ret =  save_user_config(serial_fd);
        if(ret < 0){
            printf("CHIP_CRTL_SAVE_USER_CONFIG  failed!\n");
            goto end;
        }
        printf("CHIP_CRTL_SAVE_USER_CONFIG success!\n");
    } else if(ctrl_type == CHIP_CRTL_GET_USER_CONFIG){
        int ret =  get_user_config(serial_fd, chip_ctrl->get_user_config.user_data, chip_ctrl->get_user_config.size);
        if(ret < 0){
            printf("CHIP_CRTL_GET_USER_CONFIG  failed!\n");
            goto end;
        }
        printf("CHIP_CRTL_GET_USER_CONFIG success!\n");
    }else if(ctrl_type == TEST_UPGRADE){
        int len = 0;
        char *filename = chip_ctrl->upgrade_chip_path.filename;

        int ret = -1;
        if(strstr(filename, "pl")){//fpga
            ret = read_main_file(filename, serial_fd, &len);
            if(0 > ret){
                goto end;
            }
            update_fpga_project(serial_fd, len);
        }else if(strstr(filename, "pl") && strstr(filename, "ps")){ //fpga & riscv
            ret = read_main_file(filename, serial_fd, &len);
            if(0 > ret){
                goto end;
            }
            update_fpga_and_riscv_project(serial_fd, len);
        }else if(strstr(filename, "ps")){//riscv
            ret = read_main_file(filename, serial_fd, &len);
            if(0 > ret){
                goto end;
            }
            update_riscv_project(serial_fd, len);
        }else{
            printf("filename:{%s} err update chip failed!\n",filename);
            goto end;
        }

        char recvbuf[BUF_SIZE] = {0};
        int cnt = 0, offset = 0;
        int up_result = 0;
        while (1) {
            up_result = 0;
            if(cnt > 100)
                break;
            int n = serial_read(serial_fd, recvbuf + offset, sizeof(recvbuf) - 1);
            if (n > 0) {
                offset += n;
                
                printf("Received: %s\n", recvbuf);

                if(strstr(recvbuf, "flash write ok")){
                    recvbuf[offset] = '\0';
                    up_result = 1;
                    break;
                }

                if (offset >= sizeof(recvbuf) - 1) {
                    printf("Buffer full! Clearing buffer.\n");
                    offset = 0; // 重置偏移量
                    memset(recvbuf, 0, sizeof(recvbuf)); // 清空缓冲区
                }
            }else{
                printf("Received: None!\n");
            }
            cnt++;
            usleep(100000);
        }
        
        if(1 == up_result){
            progress_bar(1, 1);
            printf("recvbuf:[%s]\n",recvbuf);
        }else{
            goto end;
        }
        
        int i=0;
        for(int i=0; i<strlen(recvbuf); ++i){
            printf("%02x ", recvbuf[i]);
        }
        printf("\n");
    }

    close(serial_fd);
    return 0;

end:  
    close(serial_fd);
    return -1;
}

    